package org.example.springblog.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.JwtParser;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.io.Encoders;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;
import org.example.springblog.constants.Constant;


import javax.crypto.SecretKey;
import java.security.Key;
import java.util.Date;
import java.util.Map;

import static io.jsonwebtoken.SignatureAlgorithm.HS256;

@Slf4j
public class JWTUtils {
    //过期时间: 1小时的毫秒数
    private final static long EXPIRATION_DATE = 60 * 60 * 1000;
    //使用一个标签，在这里我们使用的标签是一样，
    //由于token是一个base64编码的形式
    //先将这个标签转化成base64编码，
    //再当成标签，进行生成token
    private final static String secretString = "ND/G/LsRFDTC88R/ua9ZqGn3ueqHC5Els255MdPMiF4=";
    private final static Key key = Keys.hmacShaKeyFor(Decoders.BASE64.decode(secretString));

    //生成token

    public static String  getToken(Map<String,Object> claims) throws Exception {
        String token= Jwts.builder()
                .setClaims(claims)
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_DATE))
                .signWith(key)
                .compact();
        log.info("token:{}",token);
        return token;
    }
    //生成key
    //这应该就是一个生成key的方法

    public static void genKey() throws Exception {
        SecretKey secretKey=Keys.secretKeyFor(HS256);
        String encode= Encoders.BASE64.encode(secretKey.getEncoded());
        System.out.println(encode);
    }

    //校验token
    public static Claims parseToken(String token) throws Exception {
        //这里进行改的话，是为了减少代码的冗余
        JwtParser build = Jwts.parserBuilder().setSigningKey(key).build();
        Claims body =null;
        try{
            body=build.parseClaimsJws(token).getBody();
        }catch (ExpiredJwtException e) {
            log.error("token过期，校验失败，token："+token);
        } catch (Exception e){
            log.error("token校验失败，token："+token);
        }
        return body;
    }
    //进行检查token
    public static Boolean checkToken(String token) throws Exception {
        //这里就不用写死了
       Claims body = parseToken(token);
       if(body==null) {
           return false;
       }
       return true;
    }
    public static  Integer getIdFromToken(String token) throws Exception {
        Claims body = parseToken(token);
        if(body==null) {
            return -1;
        }
        return (Integer)body.get(Constant.USER_CLAIM_ID);
    }
}
